package gov.pr.celepar.sentinela.admin.dao.postgre;

import gov.pr.celepar.sentinela.Constants;
import gov.pr.celepar.sentinela.admin.dao.UsuarioDAO;
import gov.pr.celepar.sentinela.admin.dao.factory.DAOFactoryServer;
import gov.pr.celepar.sentinela.admin.excecao.SentinelaServerException;
import gov.pr.celepar.sentinela.admin.pojo.Grupo;
import gov.pr.celepar.sentinela.admin.pojo.Sistema;
import gov.pr.celepar.sentinela.admin.pojo.Usuario;
import gov.pr.celepar.sentinela.client.dao.factory.DAOFactoryClient;
import gov.pr.celepar.sentinela.log.dao.LogDAO;
import gov.pr.celepar.sentinela.log.dao.factory.DAOFactoryLog;
import gov.pr.celepar.sentinela.util.JDBCLogger;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class PSQLUsuarioDAO implements UsuarioDAO {
	private static Log logger = LogFactory.getLog(PSQLUsuarioDAO.class);
	private LogDAO logUsuario;

	public PSQLUsuarioDAO() {
		logUsuario = DAOFactoryLog.getDAOFactory().getLogDAO(
				PSQLUsuarioDAO.class);
	}

	/*
	 * ( public boolean alterarSenha(Usuario usuario, boolean expirada, Long
	 * codAutor, String ipAutor, Long codSistema, boolean enviarNotificacao)
	 * throws Exception {
	 * 
	 * if (usuario == null) return false; if (usuario.getSenha() == null) return
	 * false;
	 * 
	 * String passCripto = Criptografia.criptografar(usuario.getLogin() +
	 * usuario.getSenha());
	 * 
	 * PreparedStatement ps = null; DAOFactoryServer dao =
	 * DAOFactoryServer.getDAOFactory(); Connection conn =
	 * dao.createConnection();
	 * 
	 * try { String s; if (expirada) s = "update usuario set
	 * senhausuario=?,datatrocasenha='2000-01-01' where codusuario=?"; else s =
	 * "update usuario set senhausuario=?,datatrocasenha=? where codusuario=?";
	 * ps = conn.prepareStatement(s); ps.setString(1, passCripto); if (expirada) {
	 * ps.setLong(2, usuario.getCodUsuario()); } else { ps.setTimestamp(2, new
	 * Timestamp(new java.util.Date().getTime())); ps.setLong(3,
	 * usuario.getCodUsuario()); } ps.setLong(2, usuario.getCodUsuario());
	 * JDBCLogger.logSQL(ps); if (ps.executeUpdate() > 0) {
	 * 
	 * logUsuario.gravarLogUsuario(consultarUsuarioLog(usuario
	 * .getCodUsuario()), codAutor, ipAutor,
	 * Constants.SENTINELA_INTERFACE_ADMIN, codSistema, "alterarSenha"); return
	 * true; } } catch (Exception e) { logger.error("", e); } finally { if (ps !=
	 * null) ps.close(); dao.closeConnection(conn); } return false; }
	 */

	/*
	 * public boolean alterarLogin(Long codUsuario, String newLogin, String
	 * email, Long codAutor, String ipAutor, String interfaceAcesso, Long
	 * codSistema) throws Exception {
	 * 
	 * PreparedStatement sql = null; DAOFactoryServer dao =
	 * DAOFactoryServer.getDAOFactory(); Connection conn =
	 * dao.createConnection(); ResultSet rs = null; try {
	 * conn.setAutoCommit(false); if (this.existeLoginUsuario(newLogin, conn)) {
	 * throw new SentinelaServerException( "J� existe um usu�rio cadastrado com
	 * o login desejado."); }
	 * 
	 * sql = conn.prepareStatement("select senhapadrao," +
	 * "indicativosenhaaleatoria," + "mailorigem, mailserver, mailassunto," +
	 * "mensagemtrocasenha from sentinelaParametros"); rs = sql.executeQuery();
	 * JDBCLogger.logSQL(sql); rs.next(); String senhaPadrao =
	 * rs.getString("senhapadrao"); boolean aleatoria =
	 * rs.getBoolean("indicativosenhaaleatoria"); String emailOrigem =
	 * rs.getString("mailorigem"); String emailServer =
	 * rs.getString("mailserver"); String emailSubject =
	 * rs.getString("mailassunto"); String emailMensagem =
	 * rs.getString("mensagemtrocasenha");
	 * 
	 * String senhaGerada = senhaPadrao; if (aleatoria) { senhaGerada =
	 * AutenticacaoFacade.gerarNovaSenha(); } String passCripto =
	 * Criptografia.criptografar(newLogin + senhaGerada);
	 * 
	 * StringBuffer query = new StringBuffer(); query.append("update usuario set
	 * ").append( "loginUsuario=?, senhaUsuario=? ").append( "where codUsuario=?
	 * ");
	 * 
	 * sql = conn.prepareStatement(query.toString()); sql.setString(1,
	 * newLogin); sql.setString(2, passCripto); sql.setLong(3, codUsuario); int
	 * result = sql.executeUpdate(); JDBCLogger.logSQL(sql); if (result == 0) {
	 * if (result == 0) { throw new SentinelaServerException( "Altera��o do
	 * login do usu�rio falhou... cod: " + codUsuario + ", novo login: " +
	 * newLogin + "."); } } // Envio do e-mail SentinelaMail mail = new
	 * SentinelaMail();
	 * 
	 * emailMensagem = mail.substituirFrase(1, emailMensagem, senhaGerada);
	 * mail.enviarMailSimples(emailServer, emailSubject, email, emailOrigem,
	 * emailMensagem);
	 * 
	 * conn.commit();
	 * logUsuario.gravarLogUsuario(consultarUsuarioLog(codUsuario), codAutor,
	 * ipAutor, interfaceAcesso, codSistema, "alterarLogin"); } catch
	 * (SentinelaServerException e) { logger.error("", e); conn.rollback();
	 * throw e; } catch (Exception e) { logger.error("", e); conn.rollback();
	 * throw e; } finally { if (sql != null) sql.close();
	 * dao.closeConnection(conn); }
	 * 
	 * return false; }
	 */

	// seleciona todos os grupos ativos que o usu�rio est� vinculado
	public Collection<Grupo> getGruposVinculados(Long codUsuario)
			throws Exception {
		Collection<Grupo> col = new ArrayList<Grupo>();
		PreparedStatement ps = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();

		try {
			PSQLGrupoDAO grupoDao = new PSQLGrupoDAO();
			String s = "select ug.codgrupo from usuariogrupo ug, grupo g where ug.codusuario=? and g.ativo=? and ug.codgrupo = g.codgrupo order by g.nomegrupo";
			ps = conn.prepareStatement(s);
			ps.setLong(1, codUsuario);
			ps.setBoolean(2, true);
			ResultSet rs = ps.executeQuery();
			JDBCLogger.logSQL(ps);
			while (rs.next()) {
				long codgrupo = rs.getLong("codgrupo");
				Grupo g = grupoDao.consultar(codgrupo, conn);
				col.add(g);
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (ps != null)
				ps.close();
			dao.closeConnection(conn);
		}
		return col;
	}

	public Collection<Grupo> getGruposNaoVinculadosSemModelo(Long codUsuario)
			throws Exception {

		return getGruposNaoVinculados(codUsuario, true);
	}

	public Collection<Grupo> getGruposNaoVinculados(Long codUsuario)
			throws Exception {

		return getGruposNaoVinculados(codUsuario, false);
	}

	private Collection<Grupo> getGruposNaoVinculados(Long codUsuario,
			boolean semModelo) throws Exception {
		Collection<Grupo> col = new ArrayList<Grupo>();
		PreparedStatement ps = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		try {
			PSQLGrupoDAO grupoDao = new PSQLGrupoDAO();
			String s = "select g.codgrupo from grupo g where ";
			if (semModelo)
				s += " g.grupomodelo=? and ";
			s += " g.ativo=? and g.codgrupo not in (select codgrupo from usuariogrupo where codusuario=?) order by g.nomegrupo";
			ps = conn.prepareStatement(s);
			if (semModelo) {
				ps.setBoolean(1, false);
				ps.setBoolean(2, true);
				ps.setLong(3, codUsuario);
			} else {
				ps.setBoolean(1, true);
				ps.setLong(2, codUsuario);
			}
			ResultSet rs = ps.executeQuery();
			JDBCLogger.logSQL(ps);
			while (rs.next()) {
				long codgrupo = rs.getInt("codgrupo");
				Grupo g = grupoDao.consultar(codgrupo, conn);
				col.add(g);
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (ps != null)
				ps.close();
			dao.closeConnection(conn);
		}
		return col;
	}

	public void vincularUsuarioGrupo(Long[] grupos, Long codUsuario,
			Long codAutor) throws Exception {
		PreparedStatement ps = null;
		PreparedStatement ss = null;
		PreparedStatement ts = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		conn.setAutoCommit(false);
		try {
			ps = conn
					.prepareStatement("select count(*) as vinculados from usuarioGrupo where codgrupo=? and codusuario=?");
			ss = conn
					.prepareStatement("insert into usuarioGrupo(codgrupo,codusuario) values(?,?)");
			ts = conn
					.prepareStatement("insert into log_usuario_grupo (codusuario, codgrupo, datahora, acesso, autor) values(?,?,?,?,?)");
			for (int i = 0; i < grupos.length; i++) {
				Long codGrupo = grupos[i];
				ps.clearParameters();
				ps.setLong(1, codGrupo);
				ps.setLong(2, codUsuario);
				ResultSet rs = ps.executeQuery();
				JDBCLogger.logSQL(ps);
				rs.next();
				if (rs.getInt("vinculados") == 0) {
					ss.clearParameters();
					ss.setLong(1, codGrupo);
					ss.setLong(2, codUsuario);
					ss.executeUpdate();
					JDBCLogger.logSQL(ss);

					ts.clearParameters();
					ts.setLong(1, codUsuario);
					ts.setLong(2, codGrupo);
					ts.setTimestamp(3, new Timestamp(new Date().getTime()));
					ts.setBoolean(4, true);
					ts.setLong(5, codAutor);
					ts.executeUpdate();
					JDBCLogger.logSQL(ts);

					logger.debug("V�nculo inserido");
				} else
					logger.debug("V�nculo j� existente!!");

			}
			conn.commit();
		} catch (Exception e) {
			conn.rollback();
			logger.error("", e);
			throw e;
		} finally {
			if (ps != null)
				ps.close();
			if (ss != null)
				ss.close();
			dao.closeConnection(conn);
		}
	}

	public void desvincularUsuarioGrupo(Long[] grupos, Long codUsuario,
			Long codAutor) throws Exception {
		PreparedStatement ps = null;
		PreparedStatement ss = null;
		PreparedStatement ts = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		conn.setAutoCommit(false);

		try {
			ps = conn
					.prepareStatement("select count(*) as vinculados from usuarioGrupo where codgrupo=? and codusuario=?");
			ss = conn
					.prepareStatement("delete from usuarioGrupo where codgrupo=? and codusuario=?");
			ts = conn
					.prepareStatement("insert into log_usuario_grupo (codusuario, codgrupo, datahora, acesso, autor) values(?,?,?,?,?)");
			for (int i = 0; i < grupos.length; i++) {
				Long codGrupo = grupos[i];
				ps.clearParameters();
				ps.setLong(1, codGrupo);
				ps.setLong(2, codUsuario);
				ResultSet rs = ps.executeQuery();
				JDBCLogger.logSQL(ps);
				rs.next();
				if (rs.getInt("vinculados") > 0) {
					ss.clearParameters();
					ss.setLong(1, codGrupo);
					ss.setLong(2, codUsuario);
					ss.executeUpdate();
					JDBCLogger.logSQL(ss);

					ts.clearParameters();
					ts.setLong(1, codUsuario);
					ts.setLong(2, codGrupo);
					ts.setTimestamp(3, new Timestamp(new Date().getTime()));
					ts.setBoolean(4, false);
					ts.setLong(5, codAutor);
					ts.executeUpdate();
					JDBCLogger.logSQL(ts);
					logger.debug("V�nculo retirado");
				} else
					logger.debug("V�nculo inexistente!!");
			}
			conn.commit();
		} catch (Exception e) {
			conn.rollback();
			logger.error("", e);
			throw e;
		} finally {
			if (ps != null)
				ps.close();
			dao.closeConnection(conn);
		}
	}

	public synchronized void incluir(Usuario usuario, Long codAutor,
			String ipAutor, String interfaceAcesso, Long codSistema)
			throws Exception {
		PreparedStatement sqlParam = null;
		PreparedStatement sql = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		conn.setAutoCommit(false);

		try {

			/*
			sqlParam = conn.prepareStatement("select 	" + "senhapadrao,"
					+ "indicativosenhaaleatoria," + "mailorigem,"
					+ "mailserver," + "mailassunto,"
					+ "mensagemcadastrousuario " + "from sentinelaParametros");
			ResultSet rs = sqlParam.executeQuery();
			JDBCLogger.logSQL(sqlParam);
			rs.next();
			String senhaPadrao = rs.getString("senhapadrao");
			boolean aleatoria = rs.getBoolean("indicativosenhaaleatoria");
			String emailOrigem = rs.getString("mailorigem");
			String emailServer = rs.getString("mailserver");
			String emailSubject = rs.getString("mailassunto");
			String emailMensagem = rs.getString("mensagemcadastrousuario");
			

			String senhaGerada = senhaPadrao;
			if (aleatoria) {
				senhaGerada = AutenticacaoFacade.gerarNovaSenha();
			}
			String passCripto = Criptografia.criptografar(usuario.getLogin()
					+ senhaGerada);

			*/
			usuario.setDataCadastro(new java.util.Date());
			usuario.setAtivo(true);
			usuario.setRoot(false);
			usuario.setBloqueado(false);
//			usuario.setSenha(passCripto);
			usuario.setTentativasSenhaErrada(0);

			sql = conn
					.prepareStatement("insert into usuario("
							+ "nomeusuario, loginusuario, emailusuario,"
							+ "telefone, identidadeusuario, orgaoexpedidor, cpfusuario,"
							+ "datacadastrousuario,"
							+ "indicativoUsuarioativo, root,"
							+ "indicativobloqueio, senhausuario,"
							+ "tentativassenhaerrada"
							+ ")values( ?,?,?,?,?,?,?,?,?,?,?,?,?);");

			sql.setString(1, usuario.getNome());
			sql.setString(2, usuario.getLogin());
			sql.setString(3, usuario.getEmail());
			sql.setString(4, usuario.getTelefone());
			sql.setString(5, usuario.getIdentidade());
			sql.setString(6, usuario.getOrgaoExpedidor());
			sql.setString(7, usuario.getCpf());
			sql.setTimestamp(8, new Timestamp(usuario.getDataCadastro()
					.getTime()));
			sql.setBoolean(9, usuario.getAtivo());
			sql.setBoolean(10, usuario.getRoot());
			sql.setBoolean(11, usuario.getBloqueado());
			sql.setString(12, usuario.getSenha());
			sql.setInt(13, usuario.getTentativasSenhaErrada());

			int result = sql.executeUpdate();
			JDBCLogger.logSQL(sql);
			if (result == 0) {
				conn.rollback();
				throw new SentinelaServerException(
						"inclus�o de usuario falhou, executeUpdate = 0,"
								+ usuario.toString());
			}
			conn.commit();

			long idUsuario = this.getCodUsuarioByLogin(usuario.getLogin());
			usuario.setCodUsuario(idUsuario);
			logUsuario.gravarLogUsuario(consultarUsuarioLog(usuario
					.getCodUsuario()), codAutor, ipAutor, interfaceAcesso,
					codSistema, "incluir");

			/*
			// Envio do e-mail
			SentinelaMail mail = new SentinelaMail();
			emailMensagem = mail.substituirFrase(1, emailMensagem, usuario
					.getNome());
			emailMensagem = mail.substituirFrase(2, emailMensagem, usuario
					.getLogin());
			emailMensagem = mail.substituirFrase(3, emailMensagem, senhaGerada);
			mail.enviarMailSimples(emailServer, emailSubject, usuario
					.getEmail(), emailOrigem, emailMensagem);
			*/

		} catch (SentinelaServerException e) {
			conn.rollback();
			logger.error("", e);
			throw e;
		} catch (Exception e) {
			conn.rollback();
			logger.error("", e);
			throw e;
		} finally {
			if (sql != null)
				sql.close();
			dao.closeConnection(conn);
		}
	}

	public void alterar(Usuario alterado, Long codAutor, String ipAutor,
			Long codSistema) throws Exception {
		PreparedStatement sql = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		try {

			StringBuffer query = new StringBuffer();
			query.append("update usuario set ").append(
					"nomeUsuario=?, emailUsuario=?,").append(
					"telefone=?, identidadeUsuario=?, orgaoexpedidor=?, ")
					.append("senhausuario=?, cpfusuario=?, loginusuario=?");

			if (alterado.getAtivo() != null)
				query.append(" ,indicativoUsuarioAtivo=? ");
			if (alterado.getBloqueado() != null)
				query.append(" ,indicativobloqueio=? ");
			if (alterado.getTentativasSenhaErrada() != null)
				query.append(" ,tentativassenhaerrada=? ");
			if (alterado.getDataHoraUltimaSenhaErrada() != null)
				query.append(" ,dataHOraSenhaErrada  =? ");
			if (alterado.getDataTrocaSenha() != null)
				query.append(" ,dataTrocaSenha  =? ");

			query.append("where codUsuario=? ");

			sql = conn.prepareStatement(query.toString());

			int i = 1;
			sql.setString(i++, alterado.getNome());
			sql.setString(i++, alterado.getEmail());
			sql.setString(i++, alterado.getTelefone());
			sql.setString(i++, alterado.getIdentidade());
			sql.setString(i++, alterado.getOrgaoExpedidor());
			sql.setString(i++, alterado.getSenha());
			sql.setString(i++, alterado.getCpf());
			sql.setString(i++, alterado.getLogin());

			if (alterado.getAtivo() != null)
				sql.setBoolean(i++, alterado.getAtivo());
			if (alterado.getBloqueado() != null)
				sql.setBoolean(i++, alterado.getBloqueado());
			if (alterado.getTentativasSenhaErrada() != null)
				sql.setInt(i++, alterado.getTentativasSenhaErrada());
			if (alterado.getDataHoraUltimaSenhaErrada() != null)
				sql.setDate(i++, new java.sql.Date(alterado
						.getDataHoraUltimaSenhaErrada().getTime()));
			if (alterado.getDataTrocaSenha() != null)
				sql.setDate(i++, new java.sql.Date(alterado
						.getDataTrocaSenha().getTime()));			

			sql.setLong(i++, alterado.getCodUsuario());
			int result = sql.executeUpdate();

			JDBCLogger.logSQL(sql);

			if (result == 0) {
				throw new SentinelaServerException(
						"alteracao de usuario falhou, executeUpdate = 0,"
								+ alterado.toString());
			}
			logger.info("Gravando log de altera��o de usu�rio");
			logUsuario.gravarLogUsuario(consultarUsuarioLog(alterado
					.getCodUsuario()), codAutor, ipAutor,
					Constants.SENTINELA_INTERFACE_ADMIN, codSistema, "alterar",
					conn);
		} catch (SentinelaServerException e) {
			logger.error("", e);
			throw e;
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (sql != null)
				sql.close();
			dao.closeConnection(conn);
		}
	}

	private boolean existeLoginUsuario(String login, Connection conn)
			throws Exception {
		PreparedStatement sql = null;
		ResultSet rs = null;
		try {
			sql = conn
					.prepareStatement("select codusuario from usuario where upper(loginusuario) like upper(?) ");
			sql.setString(1, login);
			rs = sql.executeQuery();
			JDBCLogger.logSQL(sql);
			if (rs.next()) {
				return true;
			}
		} catch (SQLException e) {
			logger
					.error(
							"Erro ao verificar exist�ncia de usu�rio com o mesmo login",
							e);
			throw e;
		}
		return false;
	}

	public boolean existeCpfUsuario(String cpf) throws Exception {
		boolean resultado;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		try {
			resultado = existeCpfUsuario(cpf, conn);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			dao.closeConnection(conn);
		}
		return resultado;
	}

	public boolean existeLoginUsuario(String login) throws Exception {
		boolean resultado;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		try {
			resultado = existeLoginUsuario(login, conn);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			dao.closeConnection(conn);
		}
		return resultado;
	}

	private boolean existeCpfUsuario(String cpf, Connection conn)
			throws Exception {
		PreparedStatement sql = null;
		ResultSet rs = null;
		try {
			sql = conn
					.prepareStatement("select codusuario from usuario where cpfusuario = ? ");
			sql.setString(1, cpf);
			rs = sql.executeQuery();
			JDBCLogger.logSQL(sql);
			if (rs.next()) {
				return true;
			}
		} catch (SQLException e) {
			logger.error(
					"Erro ao verificar exist�ncia de usu�rio com o mesmo CPF",
					e);
			throw e;
		}
		return false;
	}

	Usuario consultar(Long codigo, Connection conn) throws Exception {
		PreparedStatement sql = null;
		PreparedStatement sqlGrupoADM = null;
		try {
			sql = conn.prepareStatement("select " + "nomeUsuario,"
					+ "loginUsuario," + "emailUsuario," + "identidadeUsuario,"
					+ "orgaoexpedidor," + "cpfUsuario," + "telefone,"
					+ "senhausuario, " + "datacadastrousuario,"
					+ "datatrocasenha," + "datahorasenhaerrada,"
					+ "tentativassenhaerrada," + "indicativoUsuarioAtivo,"
					+ "root," + "indicativobloqueio "
					+ "from usuario where codUsuario=? "
			/* + "and indicativousuarioativo=true" */);

			sql.setLong(1, codigo);
			ResultSet rs = sql.executeQuery();
			JDBCLogger.logSQL(sql);
			if (rs.next()) {
				Usuario usuario = new Usuario();
				usuario.setCodUsuario(codigo);
				usuario.setNome(rs.getString("nomeUsuario"));
				usuario.setLogin(rs.getString("loginUsuario"));
				usuario.setEmail(rs.getString("emailUsuario"));
				usuario.setIdentidade(rs.getString("identidadeUsuario"));
				usuario.setOrgaoExpedidor(rs.getString("orgaoexpedidor"));
				usuario.setCpf(rs.getString("cpfUsuario"));
				usuario.setTelefone(rs.getString("telefone"));
				usuario.setDataCadastro(rs.getTimestamp("datacadastrousuario"));
				usuario.setDataTrocaSenha(rs.getTimestamp("datatrocasenha"));
				usuario.setDataHoraUltimaSenhaErrada(rs
						.getTimestamp("datahorasenhaerrada"));
				usuario.setTentativasSenhaErrada(rs
						.getInt("tentativassenhaerrada"));
				usuario.setAtivo(rs.getBoolean("indicativoUsuarioAtivo"));
				usuario.setRoot(rs.getBoolean("root"));
				usuario.setBloqueado(rs.getBoolean("indicativobloqueio"));
				usuario.setSenha(rs.getString("senhausuario"));

				String queryGrupoADM = "select ug.codgrupo from usuariogrupo ug"
						+ " where ug.codgrupo in (select gruporaiz from sentinelaparametros)"
						+ " and ug.codusuario=?";
				sqlGrupoADM = conn.prepareStatement(queryGrupoADM);
				sqlGrupoADM.setLong(1, usuario.getCodUsuario());
				ResultSet rsGrupoADM = sqlGrupoADM.executeQuery();
				JDBCLogger.logSQL(sqlGrupoADM);
				if (rsGrupoADM.next())
					usuario.setRoot(true);
				else
					usuario.setRoot(false);
				sqlGrupoADM.close();

				return usuario;
			}
			return null;
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (sql != null)
				sql.close();
		}
	}

	public Usuario consultar(Long codigo) throws Exception {
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		try {
			return consultar(codigo, conn);
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			dao.closeConnection(conn);
		}
	}

	public void excluir(Usuario usuario, Long codAutor, String ipAutor,
			String interfaceAcesso, Long codSistema) throws Exception {
		PreparedStatement sql = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		conn.setAutoCommit(false);
		usuario.setAtivo(false);
		try {
			sql = conn
					.prepareStatement("update usuario set indicativousuarioativo=? where codusuario = ?");
			sql.setBoolean(1, false);
			sql.setLong(2, usuario.getCodUsuario());
			sql.executeUpdate();
			JDBCLogger.logSQL(sql);

			sql = conn
					.prepareStatement("delete from usuarioGrupo where codusuario=?");
			sql.setLong(1, usuario.getCodUsuario());
			sql.executeUpdate();
			JDBCLogger.logSQL(sql);

			sql = conn
					.prepareStatement("insert into log_usuario_grupo (codusuario, codgrupo, datahora, acesso, autor) select codusuario, codgrupo,?,?,? from usuariogrupo where codusuario = ?");
			sql.setTimestamp(1, new Timestamp(new Date().getTime()));
			sql.setBoolean(2, false);
			sql.setLong(3, codAutor);
			sql.setLong(4, usuario.getCodUsuario());
			sql.executeUpdate();
			JDBCLogger.logSQL(sql);

			conn.commit();
			logUsuario.gravarLogUsuario(consultarUsuarioLog(usuario
					.getCodUsuario()), codAutor, ipAutor, interfaceAcesso,
					codSistema, "excluir");
			/*
			 * sql = conn.prepareStatement("delete from logauditoria where
			 * codusuario=?"); sql.setLong(1, usuario.getCodUsuario());
			 * sql.executeUpdate(); JDBCLogger.logSQL(sql);
			 * 
			 * if(sql!=null)sql.close();
			 * 
			 * sql = conn.prepareStatement("delete from usuariosistema where
			 * codusuario=?"); sql.setLong(1, usuario.getCodUsuario());
			 * sql.executeUpdate(); JDBCLogger.logSQL(sql);
			 * 
			 * if(sql!=null)sql.close();
			 * 
			 * sql = conn.prepareStatement("delete from usuario where
			 * codusuario=?"); sql.setLong(1, usuario.getCodUsuario());
			 * sql.executeUpdate(); JDBCLogger.logSQL(sql);
			 * 
			 * conn.commit();
			 */
		} catch (Exception e) {
			conn.rollback();
			logger.error("", e);
			throw e;
		} finally {
			if (sql != null)
				sql.close();
			dao.closeConnection(conn);
		}
	}

	public Collection<Usuario> listarUsuariosRoot(Integer numPag)
			throws Exception {

		Collection<Usuario> c = new ArrayList<Usuario>();
		PreparedStatement sql = null;
		DAOFactoryServer dao = null;
		Connection conn = null;
		try {
			dao = DAOFactoryServer.getDAOFactory();
			conn = dao.createConnection();
			sql = conn.prepareStatement(" select   " + "codUsuario, "
					+ "nomeUsuario, " + "loginusuario," + "cpfusuario "
					+ "from " + "usuario  "
					+ "where root=? and indicativousuarioativo=? "
					+ "order by nomeUsuario ");
			sql.setBoolean(1, true);
			sql.setBoolean(2, true);
			ResultSet rs = sql.executeQuery();
			JDBCLogger.logSQL(sql);
			while (rs.next()) {
				Usuario u = new Usuario();
				u.setCodUsuario(rs.getLong("codUsuario"));
				u.setNome(rs.getString("nomeUsuario"));
				u.setLogin(rs.getString("loginusuario"));
				u.setCpf(rs.getString("cpfusuario"));
				c.add(u);
			}
		} catch (SentinelaServerException e) {
			logger.error("", e);

		} catch (Exception e) {
			logger.error("", e);

		} finally {
			try {
				if (sql != null)
					sql.close();
				dao.closeConnection(conn);
			} catch (Exception e) {
				logger.error("", e);
			}
		}
		return c;
	}

	public Collection<Usuario> listar() {
		Collection<Usuario> c = new ArrayList<Usuario>();

		PreparedStatement sql = null;
		DAOFactoryServer dao = null;
		Connection conn = null;
		try {
			dao = DAOFactoryServer.getDAOFactory();
			conn = dao.createConnection();
			sql = conn
					.prepareStatement(" select codUsuario, "
							+ "nomeUsuario from usuario where indicativousuarioativo = ?"
							+ "order by nomeUsuario ");

			sql.setBoolean(1, true);

			ResultSet rs = sql.executeQuery();
			JDBCLogger.logSQL(sql);
			while (rs.next()) {
				Usuario u = new Usuario();
				u.setCodUsuario(rs.getLong("codUsuario"));
				u.setNome(rs.getString("nomeUsuario"));
				c.add(u);
			}
		} catch (SentinelaServerException e) {
			logger.error("", e);

		} catch (Exception e) {
			logger.error("", e);

		} finally {
			try {
				if (sql != null)
					sql.close();
				dao.closeConnection(conn);
			} catch (Exception e) {
				logger.error("", e);
			}
		}
		return c;
	}

	public Collection<Usuario> pesquisarPaginado(Integer numPagina,
			String nome, String email, String cpf, String login)
			throws Exception {
		return pesquisarPaginado(numPagina, nome, email, cpf, login, false);
	}

	public Collection<Usuario> pesquisarPaginado(Integer numPagina,
			String nome, String email, String cpf, String login,
			boolean exibirInativos) throws Exception {
		PreparedStatement sql = null;
		Collection<Usuario> col = new ArrayList<Usuario>();
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();

		try {
			int numFetch = Constants.QUANTIDADE_REGISTROS_GRID.intValue();

			StringBuffer sb = new StringBuffer();
			StringBuffer parametro;
			sb.append("select codusuario from usuario ");

			int filtros = 0;

			if (StringUtils.isNotBlank(nome) || 
				StringUtils.isNotBlank(email) || 
				StringUtils.isNotBlank(cpf) ||
				StringUtils.isNotBlank(login)) {

				sb.append(" where ");

				if (StringUtils.isNotBlank(nome)) {
					sb.append(" nomeusuario ilike ? ");
					filtros++;
				}

				if (StringUtils.isNotBlank(email)) {
					if (filtros > 0)
						sb.append(" and ");

					sb.append(" emailusuario ilike ? ");
					filtros++;
				}

				if (StringUtils.isNotBlank(cpf)) {
					if (filtros > 0)
						sb.append(" and ");

					sb.append(" cpfusuario=? ");
					filtros++;
				}

				if (StringUtils.isNotBlank(login)) {
					if (filtros > 0)
						sb.append(" and ");

					sb.append(" loginusuario ilike ? ");
					filtros++;
				}
			}

			if (!exibirInativos) {
				if (filtros > 0)
					sb.append(" and ");
				else
					sb.append(" where ");

				sb.append(" indicativousuarioativo = true ");
			}

			sb.append(" order by nomeusuario limit ? offset ?");

			sql = conn.prepareStatement(sb.toString());

			filtros = 0;

			if (StringUtils.isNotBlank(nome)) {
				filtros++;
				nome = nome.replace(' ', '%');
				parametro = new StringBuffer(nome);
				parametro.insert(0, '%');
				parametro.append('%');
				sql.setString(filtros, parametro.toString());
			}

			if (StringUtils.isNotBlank(email)) {
				filtros++;
				parametro = new StringBuffer(email);
				parametro.append('%');
				sql.setString(filtros, parametro.toString());
			}

			if (StringUtils.isNotBlank(cpf)) {
				filtros++;
				parametro = new StringBuffer(cpf);
				sql.setString(filtros, parametro.toString());
			}

			if (StringUtils.isNotBlank(login)) {
				filtros++;
				parametro = new StringBuffer(login);
				parametro.insert(0, '%');
				parametro.append('%');
				sql.setString(filtros, parametro.toString());
			}

			filtros++;
			sql.setInt(filtros, numFetch);
			filtros++;
			sql.setInt(filtros, (numPagina - 1) * numFetch);

			JDBCLogger.logSQL(sql);
			ResultSet rs = sql.executeQuery();

			while (rs.next()) {
				long cod = rs.getInt("codusuario");
				Usuario user = consultar(cod, conn);
				col.add(user);
			}

		} catch (SentinelaServerException e) {
			logger.error("", e);
			throw e;
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (sql != null)
				sql.close();
			dao.closeConnection(conn);
		}
		return col;
	}

	public Collection<Usuario> pesquisarPaginado(Integer numPagina,
			String nome, String email, String cpf, String login,
			boolean exibirInativos, long codAutor) throws Exception {
		PreparedStatement sql = null;
		Collection<Usuario> col = new ArrayList<Usuario>();
		String resto = new String();

		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		try {

			Collection<Grupo> gruposVinculados = getGruposVinculados(codAutor);
			if (!gruposVinculados.isEmpty()) {
				Object[] grp = gruposVinculados.toArray();
				Long[] grpVinculados = new Long[grp.length];
				String vinculados = "(";

				for (int i = 0; i < grp.length; i++) {
					grpVinculados[i] = ((Grupo) grp[i]).getCodGrupo();
					vinculados += " " + grpVinculados[i] + ", ";
				}
				vinculados += ")";

				Collection<Grupo> gruposHierarquicos = getHierarquiaGruposUsuario(
						codAutor, grpVinculados, true);
				grp = gruposHierarquicos.toArray();

				if (!gruposHierarquicos.isEmpty()) {
					resto = " (";
					grp = gruposHierarquicos.toArray();
					for (int i = 0; i < grp.length; i++) {
						resto += " " + ((Grupo) grp[i]).getCodGrupo() + " ";
						if (i != grp.length - 1)
							resto += ",";
					}
					resto += ")";
				}
			}

			int numFetch = Constants.QUANTIDADE_REGISTROS_GRID.intValue();
			StringBuffer sb = new StringBuffer();
			sb
					.append("select distinct usuario.codusuario, usuario.nomeusuario from usuario join usuariogrupo on usuariogrupo.codusuario = usuario.codusuario where usuariogrupo.codgrupo in "
							+ resto);
			if ((nome != null && !nome.trim().equals(""))
					|| (email != null && !email.trim().equals(""))
					|| (cpf != null && !cpf.trim().equals(""))
					|| (login != null && !login.trim().equals(""))) {

				sb.append(" where ");

				int filtros = 0;

				if (nome != null && !nome.trim().equals("")) {
					nome = nome.replace(' ', '%');
					sb.append(" nomeusuario ilike '%")
							.append(nome).append("%' ");
					filtros++;
				}
				if (email != null && !email.trim().equals("")) {
					if (filtros > 0)
						sb.append(" and ");
					sb.append(" emailusuario ilike '%").append(email).append(
							"'% ");
					filtros++;
				}
				if (cpf != null && !cpf.trim().equals("")) {
					if (filtros > 0)
						sb.append(" and ");
					sb.append(" cpfusuario='").append(cpf).append("' ");
					filtros++;
				}
				if (login != null && !login.trim().equals("")) {
					if (filtros > 0)
						sb.append(" and ");
					login = login.replace(' ', '%');
					sb.append(" loginusuario ilike '%").append(login).append(
							"%' ");
					filtros++;
				}
				if (!exibirInativos) {
					if (filtros > 0)
						sb.append(" and ");
					sb.append(" indicativousuarioativo = true ");
				}
			} else {
				if (!exibirInativos)
					sb.append(" where indicativousuarioativo = true ");
			}

			sb.append(" order by usuario.nomeusuario, usuario.codusuario")
					.append(" limit ").append(numFetch).append(" offset ")
					.append((numPagina - 1) * numFetch);

			sql = conn.prepareStatement(sb.toString());
			ResultSet rs = sql.executeQuery();
			JDBCLogger.logSQL(sql);
			while (rs.next()) {
				long cod = rs.getInt("codusuario");
				Usuario user = consultar(cod, conn);
				col.add(user);
			}
		} catch (SentinelaServerException e) {
			logger.error("", e);
			throw e;
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (sql != null)
				sql.close();
			dao.closeConnection(conn);
		}
		return col;
	}

	public Long contarPesquisa(String nome, String email, String cpf,
			String login) throws Exception {
		return contarPesquisa(nome, email, cpf, login, false);
	}

	public Long contarPesquisa(String nome, String email, String cpf,
			String login, boolean exibirInativos) throws Exception {
		long res = Long.valueOf(0);
		PreparedStatement sql = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		try {
			StringBuffer sb = new StringBuffer();
			sb.append("select count(*) from usuario ");

			if ((nome != null && !nome.trim().equals(""))
					|| (email != null && !email.trim().equals(""))
					|| (cpf != null && !cpf.trim().equals(""))
					|| (login != null && !login.trim().equals(""))) {

				sb.append(" where ");

				int filtros = 0;

				if (nome != null && !nome.trim().equals("")) {
					nome = nome.replace(' ', '%');
					sb.append(" nomeusuario ilike '%")
							.append(nome).append("%' ");
					filtros++;
				}
				if (email != null && !email.trim().equals("")) {
					if (filtros > 0)
						sb.append(" and ");
					sb.append(" emailusuario ilike '%").append(email).append(
							"%' ");
					filtros++;
				}
				if (cpf != null && !cpf.trim().equals("")) {
					if (filtros > 0)
						sb.append(" and ");
					sb.append(" cpfusuario='").append(cpf).append("' ");
					filtros++;
				}
				if (login != null && !login.trim().equals("")) {
					if (filtros > 0)
						sb.append(" and ");

					login = login.replace(' ', '%');
					sb.append(" loginusuario ilike '%").append(login).append(
							"%' ");
					filtros++;
				}
				if (!exibirInativos) {
					if (filtros > 0)
						sb.append(" and ");
					sb.append(" indicativousuarioativo = true ");
				}
			} else {
				if (!exibirInativos)
					sb.append(" where indicativousuarioativo = true ");
			}

			sql = conn.prepareStatement(sb.toString());

			ResultSet rs = sql.executeQuery();
			JDBCLogger.logSQL(sql);
			if (rs.next()) {
				res = rs.getLong(1);
			}

		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (sql != null)
				sql.close();
			dao.closeConnection(conn);
		}
		return res;
	}

	public Collection<Grupo> getGruposVinculadosManutencao(
			Long codUsuarioSelecionado, Long codUsuarioLogado, Long[] grupos)
			throws Exception {
		Collection<Grupo> col = new ArrayList<Grupo>();
		Collection<Grupo> colArvore = new ArrayList<Grupo>();
		Collection<Grupo> colRemover = new ArrayList<Grupo>();
		PreparedStatement ps = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();

		try {
			PSQLGrupoDAO grupoDao = new PSQLGrupoDAO();

			String strGrupos = "";
			for (int i = 0; i < grupos.length; i++) {
				strGrupos += grupos[i];
				if (i < grupos.length - 1)
					strGrupos += ",";
			}

			String s = "select ug.codgrupo from usuariogrupo ug,grupo g where g.codgrupo = ug.codgrupo and ug.codusuario=? and g.ativo=? "
					// + " and g.codgrupomanutencao in (" + strGrupos + ") "
					+ " order by g.nomegrupo";
			ps = conn.prepareStatement(s);
			ps.setLong(1, codUsuarioSelecionado);
			ps.setBoolean(2, true);
			ResultSet rs = ps.executeQuery();
			JDBCLogger.logSQL(ps);
			while (rs.next()) {
				long codgrupo = rs.getLong("codgrupo");
				Grupo g = grupoDao.consultar(codgrupo, conn);
				col.add(g);
			}

			colArvore = getHierarquiaGruposUsuario(codUsuarioLogado, grupos,
					true);

			Iterator itr = (Iterator) col.iterator();
			while (itr.hasNext()) {
				Grupo grupo = (Grupo) itr.next();
				if (!colArvore.contains(grupo))
					colRemover.add(grupo);
			}
			col.removeAll(colRemover);

		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (ps != null)
				ps.close();
			dao.closeConnection(conn);
		}
		return col;
	}

	public Collection<Grupo> getGruposNaoVinculadosManutencaoSemModelo(
			Long codUsuarioSelecionado, Long codUsuarioLogado, Long[] grupos)
			throws Exception {
		logger.debug("SEM MODELO");
		return getGruposNaoVinculadosManutencao(codUsuarioSelecionado,
				codUsuarioLogado, grupos, true);
	}

	public Collection<Grupo> getGruposNaoVinculadosManutencao(
			Long codUsuarioSelecionado, Long codUsuarioLogado, Long[] grupos)
			throws Exception {
		logger.debug("COM MODELO");
		return getGruposNaoVinculadosManutencao(codUsuarioSelecionado,
				codUsuarioLogado, grupos, false);
	}

	public Collection<Grupo> getGruposNaoVinculadosManutencao(Long codUsuario,
			Long[] grupos, Collection<Grupo> colGruposVinculados,
			boolean semModelo) throws SentinelaServerException, Exception {
		Collection<Grupo> col = new ArrayList<Grupo>();
		PSQLUsuarioDAO usuarioDao = new PSQLUsuarioDAO();

		col = usuarioDao.getHierarquiaGruposUsuario(codUsuario, grupos,
				semModelo);
		col.removeAll(colGruposVinculados);

		return col;
	}

	private Collection<Grupo> getGruposNaoVinculadosManutencao(
			Long codUsuarioSelecionado, Long codUsuarioLogado, Long[] grupos,
			boolean semModelo) throws Exception {

		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		PreparedStatement ps = null;
		Collection<Grupo> col = new ArrayList<Grupo>();
		Collection<Grupo> colFilhos = new ArrayList<Grupo>();

		try {
			PSQLGrupoDAO grupoDao = new PSQLGrupoDAO();

			String strGrupos = "";
			for (int i = 0; i < grupos.length; i++) {
				strGrupos += grupos[i];
				if (i < grupos.length - 1)
					strGrupos += ",";
			}

			String s = "select g.codgrupo from grupo g where ";
			if (semModelo)
				s += " g.grupomodelo=? and ";

			s += " g.ativo=? and g.codgrupo not in (select codgrupo from usuariogrupo where codusuario=?)"
					+ " and g.codgrupomanutencao in ("
					+ strGrupos
					+ ")"
					+ " and g.codgrupo<>codgrupomanutencao"
					+ " order by g.nomegrupo";
			ps = conn.prepareStatement(s);

			int j = 1;
			if (semModelo)
				ps.setBoolean(j++, false);

			ps.setBoolean(j++, true);
			ps.setLong(j++, codUsuarioSelecionado);

			ResultSet rs = ps.executeQuery();
			JDBCLogger.logSQL(ps);
			Grupo g = grupoDao.consultar(grupos[0], conn);
			col.add(g);

			while (rs.next()) {
				long codgrupo = rs.getLong("codgrupo");
				g = grupoDao.consultar(codgrupo, conn);
				col.add(g);
				colFilhos = buscaRecursivaGrupos(conn, codUsuarioLogado,
						codgrupo, semModelo);
				if (colFilhos != null)
					col.addAll(colFilhos);
			}

		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (ps != null)
				ps.close();
			dao.closeConnection(conn);
		}

		return col;
	}

	public Collection<Grupo> getHierarquiaGruposUsuario(Long codUsuario,
			Long[] grupos, boolean semModelo) throws Exception {

		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		PreparedStatement ps = null;
		Collection<Grupo> col = new ArrayList<Grupo>();
		Collection<Grupo> colFilhos = new ArrayList<Grupo>();

		try {
			PSQLGrupoDAO grupoDao = new PSQLGrupoDAO();

			String strGrupos = "";
			for (int i = 0; i < grupos.length; i++) {
				strGrupos += grupos[i];
				if (i < grupos.length - 1)
					strGrupos += ",";
			}

			String s = "select g.codgrupo from grupo g where ";
			if (semModelo)
				s += " g.grupomodelo=? and ";
			s += " g.ativo=? and g.codgrupomanutencao in (" + strGrupos + ")"
					+ " and g.codgrupo<>codgrupomanutencao"
					+ " order by g.nomegrupo";
			ps = conn.prepareStatement(s);

			int j = 1;
			if (semModelo)
				ps.setBoolean(j++, false);

			ps.setBoolean(j++, true);
			// ps.setLong(j++, codUsuario);

			ResultSet rs = ps.executeQuery();
			JDBCLogger.logSQL(ps);

			Grupo g = new Grupo();

			for (int x = 0; x < grupos.length; x++) {
				g = grupoDao.consultar(grupos[x], conn);
				col.add(g);
			}

			while (rs.next()) {
				long codgrupo = rs.getLong("codgrupo");
				g = grupoDao.consultar(codgrupo, conn);
				col.add(g);
				colFilhos = buscaRecursivaGrupos(conn, codUsuario, codgrupo,
						semModelo);
				if (colFilhos != null)
					col.addAll(colFilhos);
			}

		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (ps != null)
				ps.close();
			dao.closeConnection(conn);
		}

		return col;
	}

	public Collection<Grupo> getHierarquiaGruposUsuarioPesquisa(
			Long codUsuario, Long[] grupos, boolean semModelo, String nome,
			String descricao, boolean grupoADM) throws Exception {

		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		PreparedStatement ps = null;
		Collection<Grupo> col = new ArrayList<Grupo>();
		Collection<Grupo> colFilhos = new ArrayList<Grupo>();

		try {
			PSQLGrupoDAO grupoDao = new PSQLGrupoDAO();

			String strGrupos = "";
			for (int i = 0; i < grupos.length; i++) {
				strGrupos += grupos[i];
				if (i < grupos.length - 1)
					strGrupos += ",";
			}

			StringBuffer sb = new StringBuffer();
			sb.append("select g.codgrupo from grupo g where ");
			if (semModelo)
				sb.append(" g.grupomodelo=? and ");
			sb.append(" g.ativo=? and ");

			if (grupoADM)
				sb.append(" g.grupoadm=? and ");

			sb
					.append(
							"g.codgrupomanutencao in (" + strGrupos + ")"
									+ " and g.codgrupo<>codgrupomanutencao")

					.append(
							(nome != null && nome.length() != 0)
									|| (descricao != null && descricao.length() != 0) ? " and "
									: "")
					.append(
							(descricao != null && descricao.length() != 0) ? " upper(descrgrupo) LIKE UPPER('%"
									: "")
					.append(
							(descricao != null && descricao.length() != 0) ? descricao
									: "")
					.append(
							(descricao != null && descricao.length() != 0) ? "%') "
									: "")
					.append(
							(nome != null && nome.length() != 0)
									&& (descricao != null && descricao.length() != 0) ? " and "
									: "")
					.append(
							(nome != null && nome.length() != 0) ? " upper(nomegrupo) LIKE UPPER('%"
									: "").append(
							(nome != null && nome.length() != 0) ? nome : "")
					.append((nome != null && nome.length() != 0) ? "%') " : "")
					.append(" order by g.nomegrupo ");

			ps = conn.prepareStatement(sb.toString());

			int j = 1;
			if (semModelo)
				ps.setBoolean(j++, false);

			ps.setBoolean(j++, true); // ativo

			if (grupoADM)
				ps.setBoolean(j++, grupoADM); // grupoADM

			ResultSet rs = ps.executeQuery();
			JDBCLogger.logSQL(ps);
			Grupo g = new Grupo();

			for (int x = 0; x < grupos.length; x++) {
				g = grupoDao.consultar(grupos[x], conn);
				if ((nome == null || nome.equals(""))
						&& (descricao == null || descricao.equals("")))
					col.add(g);
				else if (nome != null
						&& nome.length() != 0
						&& g.getNome().toUpperCase().contains(
								nome.toUpperCase())
						|| descricao != null
						&& descricao.length() != 0
						&& g.getDescricao().toUpperCase().contains(
								descricao.toUpperCase()))
					col.add(g);
			}

			while (rs.next()) {
				long codgrupo = rs.getLong("codgrupo");
				g = grupoDao.consultar(codgrupo, conn);
				col.add(g);
				colFilhos = buscaRecursivaGruposPesquisa(conn, codUsuario,
						codgrupo, semModelo, nome, descricao, grupoADM);
				if (colFilhos != null)
					col.addAll(colFilhos);
			}

		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (ps != null)
				ps.close();
			dao.closeConnection(conn);
		}

		return col;
	}

	private Collection<Grupo> buscaRecursivaGrupos(Connection conn,
			Long codUsuario, long codGrupoPai, boolean semModelo)
			throws Exception {
		Collection<Grupo> col = new ArrayList<Grupo>();
		Collection<Grupo> colFilhos = new ArrayList<Grupo>();
		PreparedStatement ps = null;

		try {
			PSQLGrupoDAO grupoDao = new PSQLGrupoDAO();

			String s = "select g.codgrupo from grupo g where ";
			if (semModelo)
				s += " g.grupomodelo=? and ";

			s += " g.ativo=? and  g.codgrupomanutencao in (" + codGrupoPai
					+ ")";
			s += " order by g.nomegrupo";
			ps = conn.prepareStatement(s);

			int j = 1;
			if (semModelo)
				ps.setBoolean(j++, false);

			ps.setBoolean(j++, true);
			ResultSet rs = ps.executeQuery();
			JDBCLogger.logSQL(ps);
			while (rs.next()) {
				long codgrupo = rs.getLong("codgrupo");
				Grupo g = grupoDao.consultar(codgrupo, conn);
				col.add(g);
				colFilhos = buscaRecursivaGrupos(conn, codUsuario, codgrupo,
						semModelo);
				if (colFilhos != null)
					col.addAll(colFilhos);
			}

		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (ps != null)
				ps.close();
		}

		return col;
	}

	private Collection<Grupo> buscaRecursivaGruposPesquisa(Connection conn,
			Long codUsuario, long codGrupoPai, boolean semModelo, String nome,
			String descricao, boolean grupoADM) throws Exception {
		Collection<Grupo> col = new ArrayList<Grupo>();
		Collection<Grupo> colFilhos = new ArrayList<Grupo>();
		PreparedStatement ps = null;

		try {
			PSQLGrupoDAO grupoDao = new PSQLGrupoDAO();

			StringBuffer sb = new StringBuffer();
			sb.append("select g.codgrupo from grupo g where ");
			if (semModelo)
				sb.append(" g.grupomodelo=? and ");
			sb.append(" g.ativo=? and ");

			if (grupoADM)
				sb.append(" g.grupoadm=? and ");

			sb
					.append(" g.codgrupomanutencao in (" + codGrupoPai + ") ")
					.append(
							(nome != null && nome.length() != 0)
									|| (descricao != null && descricao.length() != 0) ? " and "
									: "")
					.append(
							(descricao != null && descricao.length() != 0) ? " upper(descrgrupo) LIKE UPPER('%"
									: "")
					.append(
							(descricao != null && descricao.length() != 0) ? descricao
									: "")
					.append(
							(descricao != null && descricao.length() != 0) ? "%') "
									: "")
					.append(
							(nome != null && nome.length() != 0)
									&& (descricao != null && descricao.length() != 0) ? " and "
									: "")
					.append(
							(nome != null && nome.length() != 0) ? " upper(nomegrupo) LIKE UPPER('%"
									: "").append(
							(nome != null && nome.length() != 0) ? nome : "")
					.append((nome != null && nome.length() != 0) ? "%') " : "")
					.append(" order by g.nomegrupo ");

			ps = conn.prepareStatement(sb.toString());

			int j = 1;
			if (semModelo)
				ps.setBoolean(j++, false);

			ps.setBoolean(j++, true); // ativo

			if (grupoADM)
				ps.setBoolean(j++, grupoADM); // grupoADM

			ResultSet rs = ps.executeQuery();
			JDBCLogger.logSQL(ps);
			while (rs.next()) {
				long codgrupo = rs.getLong("codgrupo");
				Grupo g = grupoDao.consultar(codgrupo, conn);
				col.add(g);
				colFilhos = buscaRecursivaGruposPesquisa(conn, codUsuario,
						codgrupo, semModelo, nome, descricao, grupoADM);
				if (colFilhos != null)
					col.addAll(colFilhos);
			}

		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (ps != null)
				ps.close();
		}

		return col;
	}

	public void atualizarUsuarioRoot(Usuario user, Long codAutor,
			String ipAutor, String interfaceAcesso, Long codSistema)
			throws Exception {
		if (user == null)
			throw new SentinelaServerException(
					"N�o foi selecionado usu�rio para atualizar!");
		PreparedStatement sql = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		try {
			sql = conn.prepareStatement("update usuario " + "set  root=? "
					+ "where codUsuario=?");
			sql.setBoolean(1, user.getRoot());
			sql.setLong(2, user.getCodUsuario());
			sql.executeUpdate();
			JDBCLogger.logSQL(sql);
			logger.debug("User=" + user.getCodUsuario() + " root:"
					+ user.getRoot());
			logUsuario.gravarLogUsuario(consultarUsuarioLog(user
					.getCodUsuario()), codAutor, ipAutor, interfaceAcesso,
					codSistema, "atualizarUsuarioRoot");
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (sql != null)
				sql.close();
			dao.closeConnection(conn);
		}
	}

	public Collection<Grupo> getInfoAcessos(Usuario usuario) throws Exception {

		Collection<Grupo> col = new ArrayList<Grupo>();
		PreparedStatement sql = null;
		PreparedStatement sqlSis = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		try {
			PSQLGrupoDAO grupoDao = new PSQLGrupoDAO();
			PSQLSistemaDAO sistemaDao = new PSQLSistemaDAO();

			sqlSis = conn
					.prepareStatement("select codsistema from gruposistema gs where codgrupo=?");

			sql = conn.prepareStatement("select g.codgrupo "
					+ "from usuariogrupo ug, grupo g "
					+ "where ug.codusuario=? and g.ativo=? and "
					+ "ug.codgrupo = g.codgrupo order by g.codgrupo ");
			sql.setLong(1, usuario.getCodUsuario());
			sql.setBoolean(2, true);
			ResultSet rs = sql.executeQuery();
			JDBCLogger.logSQL(sql);
			while (rs.next()) {
				Grupo g = grupoDao.consultar(rs.getLong("codgrupo"), conn);

				sqlSis.clearParameters();
				sqlSis.setLong(1, g.getCodGrupo());
				ResultSet rsSis = sqlSis.executeQuery();
				JDBCLogger.logSQL(sqlSis);
				Collection<Sistema> cSis = new ArrayList<Sistema>();
				while (rsSis.next()) {
					Sistema s = sistemaDao.consultar(rsSis
							.getLong("codsistema"), conn);
					cSis.add(s);
				}
				if (rsSis != null)
					rsSis.close();
				g.setSistemas(cSis);
				col.add(g);
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (sql != null)
				sql.close();
			dao.closeConnection(conn);
		}
		return col;
	}

	public Long contarUsuariosRoot() throws Exception {
		PreparedStatement sql = null;
		DAOFactoryServer dao = null;
		Connection conn = null;
		long c = Long.valueOf(0);
		try {
			dao = DAOFactoryServer.getDAOFactory();
			conn = dao.createConnection();
			sql = conn.prepareStatement(" select  count(*) " + "from usuario  "
					+ "where root=? and indicativousuarioativo = ?");

			sql.setBoolean(1, true);
			sql.setBoolean(2, true);
			ResultSet rs = sql.executeQuery();
			JDBCLogger.logSQL(sql);
			if (rs.next()) {
				c = rs.getLong(1);
			}
		} catch (SentinelaServerException e) {
			logger.error("", e);

		} catch (Exception e) {
			logger.error("", e);

		} finally {
			try {
				if (sql != null)
					sql.close();
				dao.closeConnection(conn);
			} catch (Exception e) {
				logger.error("", e);
			}
		}
		return c;
	}

	public Collection<Usuario> verificaSimilaridade(Usuario usuario)
			throws Exception {

		if (usuario == null)
			return null;

		Collection<Usuario> c = new ArrayList<Usuario>();
		PreparedStatement sql = null;
		DAOFactoryServer dao = null;
		Connection conn = null;

		try {
			dao = DAOFactoryServer.getDAOFactory();
			conn = dao.createConnection();

			/*
			 * if (this.existeLoginUsuario(usuario.getLogin(), conn)) { throw
			 * new SentinelaServerException( "J� existe um usu�rio cadastrado
			 * com o login desejado."); } else if
			 * (this.existeCpfUsuario(usuario.getCpf(), conn)) { throw new
			 * SentinelaServerException( "J� existe um usu�rio cadastrado com o
			 * CPF desejado."); }
			 */
			sql = conn
					.prepareStatement("select codusuario "
							+ "from usuario "
							+ "where "
							+ "indicativousuarioativo = ? and("
							+ "loginusuario = ? or "
							+ "emailusuario = ? or "
							+ "cpfusuario   = ? or "
							// + "(telefone is not null and telefone <> '' and
							// telefone = ?) or "
							+ "(identidadeusuario is not null and identidadeusuario <> '' and identidadeusuario = ? "
							+ " and orgaoexpedidor is not null and orgaoexpedidor <> '' and orgaoexpedidor = ? ) or "
							+ "nomeusuario = ? )" + "order by nomeusuario ");
			sql.setBoolean(1, true);
			sql.setString(2, usuario.getLogin());
			sql.setString(3, usuario.getEmail());
			sql.setString(4, usuario.getCpf());
			// sql.setString(4, usuario.getTelefone());
			sql.setString(5, usuario.getIdentidade());
			sql.setString(6, usuario.getOrgaoExpedidor());
			sql.setString(7, usuario.getNome());
			ResultSet rs = sql.executeQuery();
			JDBCLogger.logSQL(sql);
			while (rs.next()) {
				Usuario u = this.consultar(rs.getLong("codusuario"));
				c.add(u);
			}
		} catch (SentinelaServerException e) {
			logger.error("", e);
			throw e;
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			try {
				if (sql != null)
					sql.close();
				dao.closeConnection(conn);
			} catch (Exception e) {
				logger.error("", e);
			}
		}
		return c;
	}

	public Collection<Usuario> getUsuariosByGrupo(Long codGrupo)
			throws Exception {
		ArrayList<Usuario> list = null;
		PreparedStatement statement = null;
		DAOFactoryClient dao = DAOFactoryClient.getDAOFactory();
		Connection conn = null;
		try {
			conn = dao.createConnection();
			StringBuffer query = new StringBuffer();
			query.append("select u.codusuario ").append(
					"from usuario u, usuariogrupo ug ").append(
					"where u.codusuario = ug.codusuario ").append(
					"and ug.codgrupo = ? ").append(
					"and u.indicativousuarioativo = ? ").append(
					"order by u.nomeusuario ");
			statement = conn.prepareStatement(query.toString());
			statement.setLong(1, codGrupo);
			statement.setBoolean(2, true);
			ResultSet rs = statement.executeQuery();
			JDBCLogger.logSQL(statement);
			if (rs.next()) {
				list = new ArrayList<Usuario>();
				do {
					Usuario u = this.consultar(rs.getLong("codusuario"), conn);
					list.add(u);
				} while (rs.next());
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (statement != null)
				statement.close();
			dao.closeConnection(conn);
		}
		return list;
	}

	public Long getCodUsuarioByLogin(String login) throws Exception {
		PreparedStatement sql = null;
		DAOFactoryClient dao = DAOFactoryClient.getDAOFactory();
		Connection conn = null;
		try {
			conn = dao.createConnection();
			sql = conn
					.prepareStatement("select codUsuario from usuario where loginUsuario=?");

			sql.setString(1, login);
			ResultSet rs = sql.executeQuery();
			JDBCLogger.logSQL(sql);
			if (rs.next()) {
				return rs.getLong(1);
			}
			return null;
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			if (sql != null)
				sql.close();
			dao.closeConnection(conn);
		}
	}

	public void desvincularTodosGrupos(Long codUsuario, Long codAutor)
			throws Exception {
		PreparedStatement ps = null;
		PreparedStatement ts = null;
		DAOFactoryServer dao = DAOFactoryServer.getDAOFactory();
		Connection conn = dao.createConnection();
		conn.setAutoCommit(false);

		try {
			// Insere log para todos os grupos deletados
			ts = conn
					.prepareStatement("insert into log_usuario_grupo (codusuario, codgrupo, datahora, acesso, autor) select codusuario, codgrupo,?,?,? from usuariogrupo where codusuario = ?");
			ts.setTimestamp(1, new Timestamp(new Date().getTime()));
			ts.setBoolean(2, false);
			ts.setLong(3, codAutor);
			ts.setLong(4, codUsuario);
			ts.executeUpdate();
			JDBCLogger.logSQL(ts);

			// Deleta todos os grupos
			ps = conn
					.prepareStatement("delete from usuarioGrupo where codusuario=?");
			ps.setLong(1, codUsuario);
			ps.executeUpdate();
			JDBCLogger.logSQL(ps);

			conn.commit();
		} catch (Exception e) {
			conn.rollback();
			logger.error("", e);
			throw e;
		} finally {
			if (ps != null)
				ps.close();
			dao.closeConnection(conn);
		}
	}

	/*
	 * M�todos inseridos para LOG
	 * 
	 */

	public gov.pr.celepar.sentinela.log.pojo.Usuario consultarUsuarioLog(
			Long codUsuario) throws Exception {
		Usuario usuario = this.consultar(codUsuario);
		gov.pr.celepar.sentinela.log.pojo.Usuario usuarioLog = new gov.pr.celepar.sentinela.log.pojo.Usuario();

		usuarioLog.setAtivo(usuario.getAtivo());
		usuarioLog.setBloqueado(usuario.getBloqueado());
		usuarioLog.setCodUsuario(usuario.getCodUsuario());
		usuarioLog.setCpf(usuario.getCpf());
		usuarioLog.setDataCadastro(usuario.getDataCadastro());
		usuarioLog.setDataHoraUltimaSenhaErrada(usuario
				.getDataHoraUltimaSenhaErrada());
		usuarioLog.setDataTrocaSenha(usuario.getDataTrocaSenha());
		usuarioLog.setEmail(usuario.getEmail());
		usuarioLog.setIdentidade(usuario.getIdentidade());
		usuarioLog.setOrgaoExpedidor(usuario.getOrgaoExpedidor());
		usuarioLog.setLogin(usuario.getLogin());
		usuarioLog.setNome(usuario.getNome());
		usuarioLog.setRoot(usuario.getRoot());
		usuarioLog.setSenha(usuario.getSenha());
		usuarioLog.setTelefone(usuario.getTelefone());
		usuarioLog.setTentativasSenhaErrada(usuario.getTentativasSenhaErrada());

		return usuarioLog;

	}

}